package edu.hawaii.myisern.commandline;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.math.BigInteger;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import edu.hawaii.myisern.collaborations.jaxb.Collaboration;
import edu.hawaii.myisern.organizations.jaxb.Organization;
import edu.hawaii.myisern.researchers.jaxb.Researcher;

/**
 * Prints out tables containing collaborations, researchers and organizations.
 * 
 * @author Phuoc Le
 * @author Ka Yee Leung
 * @author Jared Sunouchi
 */
public class MyIsernTableCreator {

  /** Contains the XML data */
  private MyIsernXmlLoader myIsernXml;

  /** Holds the collaboration table columns. */
  private String[] collaborationTableColumns = { "Name", "Collaborating-Organizations",
      "Collaboration-Types", "Years", "Outcome-Types", "Description" };
  /** Holds the organization table columns. */
  private String[] organizationTableColumns = { "Name", "Type", "Contact", 
      "Affiliated-Researchers", "Country", "Research-Keywords", "Research-Description", 
      "Home-Page" };
  /** Holds the researcher table columns. */
  private String[] researcherTableColumns = { "Name", "Organization", "Email", "Picture-Link",
      "Bio-Statement" };

  /**
   * Initializes this instance by reading in the three example XML files.
   * 
   * @param loader The object containing the XML data.
   * @throws Exception If problems occur.
   */
  public MyIsernTableCreator(MyIsernXmlLoader loader) throws Exception {
    this.myIsernXml = loader;
  }

  /**
   * Generates table for Collaboration.
   * 
   * @return Table panel for Collaboration.
   */
  public JTable createCollaborationTable() {
    // gets the list of collaborations and creates the data array
    List<Collaboration> collaborationsList = myIsernXml.getCollaborations().getCollaboration();
    String[][] data = new String[collaborationsList.size()][collaborationTableColumns.length];
    // populates the data array with each collaboration's information
    int count = 0;
    try {
      for (Collaboration collaboration : collaborationsList) {
        data[count][0] = collaboration.getName();
        data[count][1] = createListString(collaboration.getCollaboratingOrganizations()
            .getCollaboratingOrganization());
        data[count][2] = createListString(collaboration.getCollaborationTypes()
            .getCollaborationType());

        // gets the list of collaboration years and turns it into a string

        List<BigInteger> yearsList = collaboration.getYears().getYear();
        int listSize = yearsList.size();
        int listCount = 1;
        StringBuffer yearNames = new StringBuffer();
        for (BigInteger year : yearsList) {
          if (year.toString().equals("1900")) {
            String space = " ";
            yearNames.append(space);
          }
          else {
            yearNames.append(year.toString());
          }
          if ((listCount < listSize) && (yearNames.length() > 1)) {
            String separator = ", ";
            yearNames.append(separator);
          }
          listCount++;
        }
        data[count][3] = yearNames.toString();
        data[count][4] = createListString(collaboration.getOutcomeTypes().getOutcomeType());
        data[count][5] = collaboration.getDescription();
        count++;
      }
    }
    catch (Exception e) {
      // catch empty yearlist and outcometype list
      System.out.println("Empty Years or OutcomeTypes");
    }

    // creates the JTable
    final JTable table = new JTable(data, collaborationTableColumns);

    return table;
  }

  /**
   * Generates table for Organizations.
   * 
   * @return Table panel for Organizations
   */
  public JTable createOrganizationTable() {
    // gets the list of organizations and creates the data array
    List<Organization> organizationsList = myIsernXml.getOrganizations().getOrganization();
    String[][] data = new String[organizationsList.size()][organizationTableColumns.length];

    // populates the data array with each organization's information
    int count = 0;
    for (Organization organization : organizationsList) {
      data[count][0] = organization.getName();
      data[count][1] = organization.getType();
      data[count][2] = organization.getContact();
      data[count][3] = createListString(organization.getAffiliatedResearchers()
          .getAffiliatedResearcher());
      data[count][4] = organization.getCountry();
      data[count][5] = createListString(organization.getResearchKeywords().getResearchKeyword());
      data[count][6] = organization.getResearchDescription();
      data[count][7] = organization.getHomePage();
      count++;
    }

    // creates the JTable
    final JTable table = new JTable(data, organizationTableColumns);

    return table;
  }

  /**
   * Generate table for Researchers.
   * 
   * @return Table panel for Researchers.
   */
  public JTable createResearcherTable() {
    // gets the list of researchers and creates the data array
    List<Researcher> researcherList = myIsernXml.getResearchers().getResearcher();
    String[][] data = new String[researcherList.size()][researcherTableColumns.length];
    int count = 0;

    // populates the data array with the researcher's information
    for (Researcher researcher : researcherList) {
      data[count][0] = researcher.getName();
      data[count][1] = researcher.getOrganization();
      data[count][2] = researcher.getEmail();
      data[count][3] = researcher.getPictureLink();
      data[count][4] = researcher.getBioStatement();
      count++;
    }

    // creates the JTable
    final JTable table = new JTable(data, researcherTableColumns);

    return table;
  }

  /**
   * Generates a string representation of a list.
   * 
   * @param listElements The list of elements that will be turned into a string.
   * @return The string representation of the list.
   */
  public String createListString(List<String> listElements) {
    int listSize = listElements.size();
    int listCount = 1;
    StringBuffer listString = new StringBuffer();
    for (String element : listElements) {
      if ((listCount < listSize) && (!(listCount == 1))) {
        element += ", ";
      }
      listString.append(element);
      listCount++;
    }

    return listString.toString();
  }

  /**
   * Generates the panel for the given table.
   * 
   * @param table The table that will turned into the panel.
   * @return The panel representation of the table.
   */
  public JPanel createJPanel(JTable table) {
    table.setPreferredScrollableViewportSize(new Dimension(1000, 600));
    table.setFillsViewportHeight(true);
    JScrollPane scrollPane = new JScrollPane(table);
    JPanel viewTable = new JPanel(new GridLayout(1, 0));
    viewTable.add(scrollPane);

    return viewTable;
  }

  /**
   * Displays the Researchers table.
   * 
   * @param loader The object containing the XML data.
   * @throws Exception If problems occur.
   */
  public static void createAndShowResearchersTable(MyIsernXmlLoader loader) throws Exception {
    MyIsernTableCreator creator = new MyIsernTableCreator(loader);
    JPanel table = new JPanel();
    table.setLayout(new BorderLayout());
    JFrame frame = new JFrame("Researchers");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel researcherPanel = creator.createJPanel(creator.createResearcherTable());
    researcherPanel.setOpaque(true);

    // add all the panels and labels to one panel and then add that panel to the frame
    table.add(researcherPanel);
    frame.setContentPane(table);

    // display tables
    frame.pack();
    frame.setVisible(true);
  }

  /**
   * Displays the Collaborations table.
   * 
   * @param loader The object containing the XML data.
   * @throws Exception If problems occur.
   */
  public static void createAndShowCollaborationsTable(MyIsernXmlLoader loader) throws Exception {
    MyIsernTableCreator creator = new MyIsernTableCreator(loader);
    JPanel table = new JPanel();
    table.setLayout(new BorderLayout());
    JFrame frame = new JFrame("Collaborations");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel collaborationPanel = creator.createJPanel(creator.createCollaborationTable());
    collaborationPanel.setOpaque(true);

    // add all the panels and labels to one panel and then add that panel to the frame
    table.add(collaborationPanel);
    frame.setContentPane(table);

    // display tables
    frame.pack();
    frame.setVisible(true);
  }

  /**
   * Displays the Organizations table.
   * 
   * @param loader The object containing the XML data.
   * @throws Exception If problems occur.
   */
  public static void createAndShowOrganizationsTable(MyIsernXmlLoader loader) throws Exception {
    MyIsernTableCreator creator = new MyIsernTableCreator(loader);
    JPanel table = new JPanel();
    table.setLayout(new BorderLayout());
    JFrame frame = new JFrame("Organizations");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel organizationPanel = creator.createJPanel(creator.createOrganizationTable());
    organizationPanel.setOpaque(true);

    // add all the panels and labels to one panel and then add that panel to the frame
    table.add(organizationPanel);
    frame.setContentPane(table);

    // display tables
    frame.pack();
    frame.setVisible(true);
  }

  /**
   * Displays the ListCollborations table.
   * 
   * @param table The table that will be displayed.
   * @param loader The object containing the XML data.
   * @throws Exception If problems occur.
   */
  public static void createAndShowCollaborationsList(JTable table, MyIsernXmlLoader loader)
      throws Exception {
    MyIsernTableCreator creator = new MyIsernTableCreator(loader);
    JPanel tablePanel = new JPanel();
    tablePanel.setLayout(new BorderLayout());
    JFrame frame = new JFrame("Collaborations List");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel collaborationPanel = creator.createJPanel(table);
    collaborationPanel.setOpaque(true);

    // add all the panels and labels to one panel and then add that panel to the frame
    tablePanel.add(collaborationPanel);
    frame.setContentPane(tablePanel);

    // display tables
    frame.pack();
    frame.setVisible(true);
  }

  /**
   * Displays three tables for Collaborations, Researchers and Organizations.
   * 
   * @param xmlLoader The object containing the XML data.
   * @throws Exception If problems occur.
   */
  public static void createAndShowAllTables(MyIsernXmlLoader xmlLoader) throws Exception {
    // create and set up the window
    JFrame frame = new JFrame("All tables");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    // create and set up the content pane
    MyIsernTableCreator loader = new MyIsernTableCreator(xmlLoader);

    // get the panel for organization table
    JPanel organizationPanel = loader.createJPanel(loader.createOrganizationTable());
    organizationPanel.setOpaque(true);

    // get the panel for collaboration table
    JPanel collaborationPanel = loader.createJPanel(loader.createCollaborationTable());
    collaborationPanel.setOpaque(true);

    // get the panel for researcher table
    JPanel researcherPanel = loader.createJPanel(loader.createResearcherTable());
    researcherPanel.setOpaque(true);

    // add all the tabbed panels to one panel and then add that panel to the frame
    JPanel tabbedPanel = new JPanel();
    JTabbedPane tabbedPane = new JTabbedPane();

    JPanel panel1 = new JPanel(false);
    panel1.setLayout(new GridLayout(1, 1));
    JTable collaborationsTable = loader.createCollaborationTable();
    collaborationsTable.setPreferredScrollableViewportSize(new Dimension(1000, 600));
    collaborationsTable.setFillsViewportHeight(true);
    JScrollPane scrollPaneCollaboration = new JScrollPane(collaborationsTable);
    panel1.add(scrollPaneCollaboration);
    tabbedPane.addTab("Collaborations Table", panel1);

    JPanel panel2 = new JPanel(false);
    panel2.setLayout(new GridLayout(1, 1));
    JTable organizationsTable = loader.createOrganizationTable();
    organizationsTable.setPreferredScrollableViewportSize(new Dimension(1000, 600));
    organizationsTable.setFillsViewportHeight(true);
    JScrollPane scrollPaneOrganization = new JScrollPane(organizationsTable);
    panel2.add(scrollPaneOrganization);
    tabbedPane.addTab("Organizations Table", panel2);

    JPanel panel3 = new JPanel(false);
    panel3.setLayout(new GridLayout(1, 1));
    JTable researchersTable = loader.createResearcherTable();
    researchersTable.setPreferredScrollableViewportSize(new Dimension(1000, 600));
    researchersTable.setFillsViewportHeight(true);
    JScrollPane scrollPaneResearcher = new JScrollPane(researchersTable);
    panel3.add(scrollPaneResearcher);
    tabbedPane.addTab("Researchers Table", panel3);

    tabbedPanel.add(tabbedPane);

    frame.add(tabbedPanel, BorderLayout.CENTER);
    frame.pack();
    frame.setVisible(true);
  }
}
